#include <cppunit/config/SourcePrefix.h>
#include "Next.h"
#include "TestNext.h"

#include <algorithm>
#include <iostream>
#include <string>

void NextTest::setUp()
{
	cout << "Test Next setUp()\n";
}
void NextTest::tearDown()
{}
// Registers the fixture into the 'registry'
CPPUNIT_TEST_SUITE_REGISTRATION( NextTest ); 
// method to test the constructor
void NextTest::testConstructor() { 
}
void NextTest::testSetNext(){
	std::cout<<std::endl<<"Testing setNext..."<<std::endl;
	Next myNextTable = Next::Next();
	myNextTable.setNext(1,2);
	CPPUNIT_ASSERT(myNextTable.isNext(1,2));
}

/*
procedure Foo{                  
	
}
*/


void NextTest::testGetSuccessor(){
	std::cout<<std::endl<<"Testing GetSuccessor..."<<std::endl;
	Next myNextTable = Next::Next();
	myNextTable.setNext(1,2);
	myNextTable.setNext(2,3);
	myNextTable.setNext(3,4);
	myNextTable.setNext(4,5);
	myNextTable.setNext(5,6);
	myNextTable.setNext(6,3);
	myNextTable.setNext(3,7);
	myNextTable.setNext(7,8);
	myNextTable.setNext(7,9);
	myNextTable.setNext(8,10);
	myNextTable.setNext(9,10);
	myNextTable.setNext(10,11);


	//Get Successor of 7
	Type::Index::Line samplec1[] = {8,9};
	Type::List::Line sample1 (samplec1, samplec1 + sizeof(samplec1)/sizeof(Type::Index::Line));
	Type::List::Line successor = myNextTable.getSuccessor(7);
	sort(successor.begin(),successor.end());
	CPPUNIT_ASSERT(successor == sample1);

}
void NextTest::testGetPredecessor(){
	std::cout<<std::endl<<"Testing testGetPredecessor..."<<std::endl;
	Next myNextTable = Next::Next();
	myNextTable.setNext(8,10);
	myNextTable.setNext(9,10);

	//Get Predecessor of 10
	Type::Index::Line samplec1[] = {8,9};
	Type::List::Line sample1 (samplec1, samplec1 + sizeof(samplec1)/sizeof(Type::Index::Line));
	Type::List::Line predcessor = myNextTable.getPredecessor(10);
	sort(predcessor.begin(),predcessor.end());
	CPPUNIT_ASSERT(predcessor == sample1);
}
void NextTest::testHasSuccessor(){
	std::cout<<std::endl<<"Testing testHasSuccessor..."<<std::endl;
	Next myNextTable = Next::Next();
	myNextTable.setNext(8,10);
	myNextTable.setNext(9,10);

	CPPUNIT_ASSERT(myNextTable.hasSuccessor(8) == true);
	CPPUNIT_ASSERT(myNextTable.hasSuccessor(11) == false);
	CPPUNIT_ASSERT(myNextTable.hasSuccessor(10) == false);
}
void NextTest::testHasPredecessor(){
	std::cout<<std::endl<<"Testing testHasPredecessor..."<<std::endl;
	Next myNextTable = Next::Next();
	myNextTable.setNext(8,10);
	myNextTable.setNext(9,10);

	CPPUNIT_ASSERT(myNextTable.hasPredecessor(8) == false);
	CPPUNIT_ASSERT(myNextTable.hasPredecessor(11) == false);
	CPPUNIT_ASSERT(myNextTable.hasPredecessor(10) == true);
}
void NextTest::testIsNext(){
	std::cout<<std::endl<<"Testing isNext..."<<std::endl;
	Next myNextTable = Next::Next();
	myNextTable.setNext(1,2);
	myNextTable.setNext(2,3);
	myNextTable.setNext(3,4);
	myNextTable.setNext(4,5);
	myNextTable.setNext(5,6);
	myNextTable.setNext(6,3);
	myNextTable.setNext(3,7);
	myNextTable.setNext(7,8);
	myNextTable.setNext(7,9);
	myNextTable.setNext(8,10);
	myNextTable.setNext(9,10);
	myNextTable.setNext(10,11);
	CPPUNIT_ASSERT_EQUAL(true, myNextTable.isNext(1,2));
	CPPUNIT_ASSERT_EQUAL(false, myNextTable.isNext(1,3));
	CPPUNIT_ASSERT_EQUAL(true, myNextTable.isNext(3,7));
	CPPUNIT_ASSERT_EQUAL(true, myNextTable.isNext(8,10));
}

/*********************************
    ety c1 c2 c3 c4
 ety 0  0  0  0  0
 p1  0  0  1  0  0
 p2  0  0  0  1  0
 p3  0  0  0  0  1
 p4  0  0  0  0  0

 next(1,2)
 next(2,3)
 next(2,4)
**********************************/
void NextTest::testSetNextBitMap(){
	Next myNextTable = Next::Next();
	myNextTable.setNext(1,2);
	myNextTable.setNext(2,3);
	myNextTable.setNext(3,4);
	CPPUNIT_ASSERT_EQUAL(false, myNextTable.isBitMapSet());
	vector<vector<bool>> sampleBitMap;
	for (int i = 0 ; i < 5; i++){
		vector<bool> temp;
		temp.clear();
		if (i==0 || i==4 ){
			temp.push_back(false);
			temp.push_back(false);
			temp.push_back(false);
			temp.push_back(false);
			temp.push_back(false);
		}else if(i==1){
			temp.push_back(false);
			temp.push_back(false);
			temp.push_back(true);
			temp.push_back(false);
			temp.push_back(false);
		}else if(i==2){
			temp.push_back(false);
			temp.push_back(false);
			temp.push_back(false);
			temp.push_back(true);
			temp.push_back(false);
		}else{
			temp.push_back(false);
			temp.push_back(false);
			temp.push_back(false);
			temp.push_back(false);
			temp.push_back(true);
		}
		sampleBitMap.push_back(temp);
	}
	myNextTable.setNextBitMap(sampleBitMap);
	CPPUNIT_ASSERT_EQUAL(true, myNextTable.isBitMapSet());
	CPPUNIT_ASSERT_EQUAL(true, myNextTable.isNext(1,2));
	CPPUNIT_ASSERT_EQUAL(true, myNextTable.isNext(2,3));
	CPPUNIT_ASSERT_EQUAL(false, myNextTable.isNext(2,4));
	CPPUNIT_ASSERT_EQUAL(false, myNextTable.isNext(2,1));
	CPPUNIT_ASSERT_EQUAL(true, myNextTable.isNext(3,4));
}